<template>
  <div class="side-setting">
    <setting-item title="整体风格设置">
      <img-checkbox-group
        @change="(values) => setTheme({ ...theme, mode: values[0] })"
        :default-values="[theme.mode]"
      >
        <img-checkbox
          title="暗色菜单风格"
          :img="require('@/assets/theme_images/dark.svg')"
          value="dark"
        />
        <img-checkbox
          title="亮色菜单风格"
          :img="require('@/assets/theme_images/light.svg')"
          value="light"
        />
        <img-checkbox
          title="深夜模式"
          :img="require('@/assets/theme_images/night.svg')"
          value="night"
        />
      </img-checkbox-group>
    </setting-item>
    <setting-item title="主题色">
      <color-checkbox-group
        @change="(values, colors) => setTheme({ ...theme, color: colors[0] })"
        :defaultValues="[palettes.indexOf(theme.color)]"
        :multiple="false"
      >
        <color-checkbox
          v-for="(color, index) in palettes"
          :key="index"
          :color="color"
          :value="index"
        />
      </color-checkbox-group>
    </setting-item>
    <a-divider />
    <setting-item title="导航设置">
      <img-checkbox-group
        @change="(values) => setLayout(values[0])"
        :default-values="[layout]"
      >
        <img-checkbox
          title="侧边导航"
          :img="require('@/assets/theme_images/side.svg')"
          value="side"
        />
        <img-checkbox
          title="顶部导航"
          :img="require('@/assets/theme_images/top.svg')"
          value="head"
        />
        <img-checkbox
          title="混合导航"
          :img="require('@/assets/theme_images/mix.svg')"
          value="mix"
        />
      </img-checkbox-group>
    </setting-item>
    <setting-item>
      <a-list :split="false">
        <a-list-item>
          内容区域宽度
          <a-select
            :getPopupContainer="getPopupContainer"
            :value="pageWidth"
            @change="setPageWidth"
            class="select-item"
            size="small"
            slot="actions"
          >
            <a-select-option value="fluid">流式</a-select-option>
            <a-select-option value="fixed">定宽</a-select-option>
          </a-select>
        </a-list-item>
        <a-list-item>
          固定Header
          <a-switch
            :checked="fixedHeader"
            slot="actions"
            size="small"
            @change="setFixedHeader"
          />
        </a-list-item>
        <a-list-item>
          固定侧边栏
          <a-switch
            :checked="fixedSideBar"
            slot="actions"
            size="small"
            @change="setFixedSideBar"
          />
        </a-list-item>
      </a-list>
    </setting-item>
    <a-divider />
    <setting-item title="其他设置">
      <a-list :split="false">
        <a-list-item>
          多页签模式
          <a-switch
            :checked="multiPage"
            slot="actions"
            size="small"
            @change="setMultiPage"
          />
        </a-list-item>
        <a-list-item>
          隐藏设置抽屉
          <a-switch
            :checked="hideSetting"
            slot="actions"
            size="small"
            @change="setHideSetting"
          />
        </a-list-item>
      </a-list>
    </setting-item>
    <a-divider />
    <setting-item title="页面切换动画">
      <a-list :split="false">
        <a-list-item>
          禁用动画
          <a-switch
            :checked="animate.disabled"
            slot="actions"
            size="small"
            @change="(val) => setAnimate({ ...animate, disabled: val })"
          />
        </a-list-item>
        <a-list-item>
          动画效果
          <a-select
            :value="animate.name"
            :getPopupContainer="getPopupContainer"
            @change="(val) => setAnimate({ ...animate, name: val })"
            class="select-item"
            size="small"
            slot="actions"
          >
            <a-select-option
              :key="index"
              :value="item.name"
              v-for="(item, index) in animates"
            >
              {{ item.alias }}
            </a-select-option>
          </a-select>
        </a-list-item>
      </a-list>
    </setting-item>
    <setting-item>
      <a-button @click="saveSetting" type="primary" icon="save">
        保存配置
      </a-button>
      <a-button
        @click="resetSetting"
        type="dashed"
        icon="redo"
        style="float: right"
      >
        重置配置
      </a-button>
    </setting-item>
  </div>
</template>

<script>
  import SettingItem from './SettingItem'
  import { ColorCheckbox, ImgCheckbox } from '@/components/checkbox'
  import Clipboard from 'clipboard'
  import { mapState, mapMutations } from 'vuex'
  import { formatConfig } from '@/utils/formatter'
  import { setting } from '@/config/default'
  import sysConfig from '@/config/config'
  import fastEqual from 'fast-deep-equal'
  import deepMerge from 'deepmerge'

  const ColorCheckboxGroup = ColorCheckbox.Group
  const ImgCheckboxGroup = ImgCheckbox.Group
  export default {
    name: 'Setting',
    components: {
      ImgCheckboxGroup,
      ImgCheckbox,
      ColorCheckboxGroup,
      ColorCheckbox,
      SettingItem,
    },
    data() {
      return {
        copyConfig: 'Sorry, you have copied nothing O(∩_∩)O~',
        isDev: process.env.NODE_ENV === 'development',
      }
    },
    computed: {
      directions() {
        return this.animates.find((item) => item.name == this.animate.name)
          .directions
      },
      ...mapState('setting', [
        'theme',
        'layout',
        'animate',
        'animates',
        'palettes',
        'multiPage',
        'weekMode',
        'fixedHeader',
        'fixedSideBar',
        'hideSetting',
        'pageWidth',
      ]),
    },
    watch: {
      'animate.name': function (val) {
        this.setAnimate({ name: val, direction: this.directions[0] })
      },
    },
    methods: {
      getPopupContainer() {
        return this.$el.parentNode
      },
      copyCode() {
        let config = this.extractConfig(false)
        this.copyConfig = `// 自定义配置，参考 ./default/setting.config.js，需要自定义的属性在这里配置即可
      module.exports = ${formatConfig(config)}
      `
        let clipboard = new Clipboard('#copyBtn')
        clipboard.on('success', () => {
          this.$message
            .success(
              `复制成功，覆盖文件 src/config/config.js 然后重启项目即可生效`
            )
            .then(() => {
              const localConfig = localStorage.getItem(
                process.env.VUE_APP_SETTING_KEY
              )
              if (localConfig) {
                console.warn(
                  '检测到本地有历史保存的主题配置，想要要拷贝的配置代码生效，您可能需要先重置配置'
                )
                this.$message.warn(
                  '检测到本地有历史保存的主题配置，想要要拷贝的配置代码生效，您可能需要先重置配置',
                  5
                )
              }
            })
          clipboard.destroy()
        })
      },
      saveSetting() {
        const closeMessage = this.$message.loading(
          '正在保存到本地，请稍后...',
          0
        )
        const config = this.extractConfig(true)
        localStorage.setItem(
          process.env.VUE_APP_SETTING_KEY,
          JSON.stringify(config)
        )
        setTimeout(closeMessage, 800)
      },
      resetSetting() {
        this.$confirm({
          title: '重置主题会刷新页面，当前页面内容不会保留，确认重置？',
          onOk() {
            localStorage.removeItem(process.env.VUE_APP_SETTING_KEY)
            window.location.reload()
          },
        })
      },
      //提取配置
      extractConfig(local = false) {
        let config = {}
        let mySetting = this.$store.state.setting
        let dftSetting = local ? deepMerge(setting, sysConfig) : setting
        Object.keys(mySetting).forEach((key) => {
          const dftValue = dftSetting[key],
            myValue = mySetting[key]
          if (dftValue != undefined && !fastEqual(dftValue, myValue)) {
            config[key] = myValue
          }
        })
        return config
      },
      ...mapMutations('setting', [
        'setTheme',
        'setLayout',
        'setMultiPage',
        'setWeekMode',
        'setFixedSideBar',
        'setFixedHeader',
        'setAnimate',
        'setHideSetting',
        'setPageWidth',
      ]),
    },
  }
</script>

<style lang="less" scoped>
  .side-setting {
    position: relative;
    min-height: 100%;
    padding: 24px;
    font-size: 14px;
    line-height: 1.5;
    word-wrap: break-word;
    background-color: @base-bg-color;
    .flex {
      display: flex;
    }
    .select-item {
      width: 80px;
    }
  }
</style>
